home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue67 / Threads / OpponentThread.pas < prev   
Encoding:
Pascal/Delphi Source File  |  2001-01-05  |  3.9 KB  |  166 lines

  1. unit OpponentThread;
  2.  
  3. interface
  4.  
  5. uses SysUtils,Classes,syncobjs,Windows,Messages,Dialogs,
  6.  //My Units
  7.  BasicThread;
  8.  
  9. type
  10.  TOpponentThread=class(TBasicThread)
  11.  private
  12.   fHiddenWordThreadID:THandle;
  13.   fMainFormHandle:THandle;
  14.   fHiddenWordLength:integer;
  15.   fPosition:integer;
  16.   fLetter:Char;
  17.   fWord:string;
  18.   procedure ExecuteLoop;
  19.   procedure PeekMessage;
  20.   procedure Initialise;
  21.   procedure WordLengthIs(const Len: integer);
  22.   procedure GuessLetterAndPosition;
  23.   procedure No;
  24.   procedure Yes;
  25.   function GotWord: boolean;
  26.  protected
  27.   procedure Execute;override;
  28.  public
  29.   constructor Create
  30.    (CreateSuspended:Boolean;const HiddenWordThreadID,MainFormHandle:THandle;var ThreadID:THandle);
  31.   destructor Destroy;override;
  32.  end;
  33.  
  34. implementation
  35.  
  36. constructor TOpponentThread.Create
  37.   (CreateSuspended:Boolean;const HiddenWordThreadID,MainFormHandle:THandle;var ThreadID:THandle);
  38. const
  39.  cCreateSuspended=TRUE;
  40. begin
  41.  fHiddenWordThreadID:=HiddenWordThreadID;
  42.  fMainFormHandle:=MainFormHandle;
  43.  inherited Create(cCreateSuspended);
  44.  ThreadID:=self.ThreadID;//Lets acquire this value before the thread terminates.
  45.  if not CreateSuspended then
  46.   Resume;
  47. end;
  48.  
  49. destructor TOpponentThread.Destroy;
  50. begin
  51.   inherited Destroy;
  52. end;
  53.  
  54. procedure TOpponentThread.Execute;
  55. var
  56.  Msg:TMsg;
  57. begin
  58.  try
  59.   //Force a message queue for the thread to be created.
  60.   Windows.PeekMessage(Msg,0,0,0,PM_NOREMOVE);
  61.   Initialise;
  62.   ExecuteLoop;
  63.  except
  64.   fException:=ExceptObject As Exception;
  65.   Synchronize(ShowException);
  66.  end;
  67.  PostMessage(fMainFormHandle,WM_Signal_ThreadTerminating,ThreadID,0);
  68. end;
  69.  
  70. procedure TOpponentThread.Initialise;
  71. begin
  72.  fHiddenWordLength:=0;
  73.  fWord:='';
  74.  PostThreadMessage(fHiddenWordThreadID,WM_Signal_RequestWordLength,ThreadID,0);
  75. end;
  76.  
  77. procedure TOpponentThread.ExecuteLoop;
  78. begin
  79.  while not Terminated do
  80.  begin
  81.   try
  82.    Windows.WaitMessage;
  83.    //Note could use GetMessage but this wouldn't allow the WM_Quit to jump its
  84.    //position in the queue.
  85.    if PeekQuitMessage then
  86.     exit;
  87.    PeekMessage;
  88.   except
  89.    //Don't reraise the exception cos we require the loop to keep executing.
  90.    on E:Exception do
  91.     begin
  92.      {Log Exception to Event Log}
  93.      fException:=E;
  94.      Synchronize(ShowException);
  95.     end;
  96.   end;
  97.  end;
  98. end;
  99.  
  100. procedure TOpponentThread.PeekMessage;
  101. var
  102.  Msg:TMsg;
  103. begin
  104.  while((not Terminated)and(Windows.PeekMessage(Msg,0,0,0,PM_Remove)))do
  105.  begin
  106.   case Msg.message of
  107.    WM_QUIT:Terminate;
  108.    WM_Signal_WordLengthIs:WordLengthIs(Msg.lParam);
  109.    WM_Signal_Yes:Yes;
  110.    WM_Signal_No:No;
  111.    else
  112.      exit;
  113.      //Translates virtual-key messages into character messages
  114.      //Not really required since the thread does not process any keyboard characters!!!
  115.      //TranslateMessage(Msg);
  116.      //Dispatches message to a window procedure with the window handle specified in the MSG structure
  117.      //Note again the window handle will be null and no action taken.
  118.      //DispatchMessage(Msg);
  119.   end;
  120.  end;
  121. end;
  122.  
  123. procedure TOpponentThread.WordLengthIs(const Len:integer);
  124. begin
  125.  fHiddenWordLength:=Len;
  126.  fWord:=StringOfChar(' ',fHiddenWordLength);
  127.  GuessLetterAndPosition;
  128. end;
  129.  
  130. procedure TOpponentThread.GuessLetterAndPosition;
  131. var
  132.  LP:LPARAM;
  133.  iLetter:integer;
  134. begin
  135.  fPosition:=Random(fHiddenWordLength)+1;//Uses binary bits 1,2,4,9,16=31
  136.  fLetter:=Char(65+Random(26));// Uses binary bits 1,2,4,8,16,32,64=127
  137.  iLetter:=Ord(fLetter);
  138.  LP:=fPosition or (iLetter shl 5);
  139.  PostThreadMessage(fHiddenWordThreadID,WM_Signal_RequestLetterUsedAtPosition,ThreadID,LP);
  140. end;
  141.  
  142. procedure TOpponentThread.No;
  143. begin
  144.  GuessLetterAndPosition;
  145. end;
  146.  
  147. procedure TOpponentThread.Yes;
  148. begin
  149.  fWord[fPosition]:=fLetter;
  150.  if GotWord then
  151.   begin
  152.    PostMessage(fMainFormHandle,WM_Signal_ThreadGotAnswer,0,0);
  153.    Terminate;
  154.   end
  155.  else
  156.   GuessLetterAndPosition;
  157. end;
  158.  
  159. function TOpponentThread.GotWord:boolean;
  160. begin
  161.  Result:=Pos(' ',fWord)=0;
  162. end;
  163.  
  164. end.
  165.  
  166.